/**
 * The contents of this file are subject to the license and copyright detailed in the LICENSE and NOTICE files at the root of the source tree and available online at
 * http://www.askosi.org/license.html
 */
package be.destin.skos.core;

import java.util.HashSet;
import java.util.LinkedList;

import org.apache.log4j.Logger;

import be.destin.util.Util;

public class SkosUtil {

	private static final Logger log = Logger.getLogger(SkosUtil.class);
	
	public static String aboutScheme(String fullHandle) {
		// This function can receive ONLY fullHandle scheme_concept and returns the scheme about (not validated)
		if (fullHandle==null || fullHandle.isEmpty()) return null;
		int posSep = fullHandle.indexOf(SchemeInterface.separator);
		if (posSep < 0) return null;
		else if (posSep == 0) return SkosManager.aboutSuffixes;
		else if ((posSep+1) == fullHandle.length()) return SkosManager.aboutPrefixes;
		else return fullHandle.substring(0, posSep);
	}

	public static HashSet<String> aboutSchemes(LinkedList<String> conceptsAbout) {
		HashSet<String> result = new HashSet<String>();
		if (conceptsAbout == null) return result;
		if (conceptsAbout.isEmpty()) return result;
		for (String about : conceptsAbout) {
			String schemeAbout = aboutScheme(about);
			if (schemeAbout != null) result.add(schemeAbout);
		}
		return result;
	}

	public static HashSet<String> aboutSchemesRelations(LinkedList<LinkedConcept> conceptsAbout) {
		HashSet<String> result = new HashSet<String>();
		if (conceptsAbout == null) return result;
		if (conceptsAbout.isEmpty()) return result;
		for (LinkedConcept aRel : conceptsAbout) {
			String about = aRel.getAbout();
			String schemeAbout = aboutScheme(about);
			if (schemeAbout != null) result.add(schemeAbout);
		}
		return result;
	}

	public static LinkedList<String> cleanList (LinkedList<String> toBeCleaned) {
		if (toBeCleaned == null) return null;
		LinkedList<String> result = new LinkedList<String>();
		for (String anEntry : toBeCleaned) {
			if (anEntry != null) {
				String cleanEntry = SkosUtil.normalizeAbout(anEntry);
				if (cleanEntry.length() > 0) result.add(cleanEntry);
			}
		}
		return result;
	}

	public static String normalizeAbout(String anAbout) {
		StringBuffer buf = new StringBuffer();
		boolean inWord = false;
		for (char curChar: anAbout.toCharArray()) {
			if (Character.isJavaIdentifierPart(curChar)) {
				buf.append(curChar);
				inWord = true;
			} else {
				if (inWord) {
					buf.append(SchemeInterface.separator);
					inWord = false;
				}
			} 
		}
		int l = buf.length() - 1;
		if (l >= 0) {
			if (buf.charAt(l) == SchemeInterface.separator) {
				buf.setLength(l);
			}
		}
		return buf.toString();
	}
	
	public static String noPrefixSuffix(String aValue) {
		aValue = aValue.trim();
		int pos = aValue.indexOf(SchemeInterface.separator);
		int begin;
		int end;
		while (pos >= 0) {
			if (pos==0) {// a suffix
				end = pos+1;
				while (end < aValue.length()) {
					if (!Character.isJavaIdentifierPart(aValue.charAt(end))) break;
					end = end + 1;
				}
				aValue = aValue.substring(end).trim();
				pos = aValue.indexOf(SchemeInterface.separator);
			} else if ((pos+1) == aValue.length()) { // a prefix?
				begin = pos-1;
				while (begin >= 0) {
					if (!Character.isJavaIdentifierPart(aValue.charAt(begin))) break;
					begin = begin - 1;
				}
				aValue = aValue.substring(0,begin+1);
				break; // certainly the last!
			} else {
				if (Character.isJavaIdentifierPart(aValue.charAt(pos+1))) {
					if (Character.isJavaIdentifierPart(aValue.charAt(pos-1))) // identifier
						pos = aValue.indexOf(SchemeInterface.separator,pos+2); // look AFTER
					else { // suffix
						end = pos+2;
						while (end < aValue.length()) {
							if (!Character.isJavaIdentifierPart(aValue.charAt(end))) break;
							end = end + 1;
						}
						aValue = aValue.substring(0,pos)+aValue.substring(end);
						pos = aValue.indexOf(SchemeInterface.separator,pos+1);
					}
				} else { // prefix
					begin = pos-2;
					while (begin >= 0) {
						if (!Character.isJavaIdentifierPart(aValue.charAt(begin))) break;
						begin = begin - 1;
					}
					aValue = aValue.substring(0,begin+1)+aValue.substring(pos+1);
					pos = aValue.indexOf(SchemeInterface.separator,begin+1);
				}
			}
		}
		return Util.noDoubleSpace(aValue);
	}
}
